home *** CD-ROM | disk | FTP | other *** search
/ Plug-In Power Pack for Netscape Communicator / Plug-In Power Pack for Netscape Communicator.iso / plugins / dataviews / dvtools / examples / programs / graph_scroll.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-08  |  16.5 KB  |  530 lines

  1. #ifndef    lint
  2. static char SccsId[]= "@(#)graph_scroll.c    V1.9    3/13/95";
  3. #endif
  4. /*
  5. |    file name - graph_scroll.c
  6. |===================================================================
  7. |
  8. |     This example illustrates how to scroll through data for a
  9. |     graph and display the different data sets in the graph. The
  10. |     graph's variable is rebound to a program variable which
  11. |     will hold the value to be displayed in the graph.  The values
  12. |     are held in an array which has been initialized to hold
  13. |     1000 data values. The example defines a tick labeling
  14. |     function in order to label the time axis based on the data
  15. |     elements being displayed. The user selects the starting
  16. |     iteration of data to display using a scrollbar.
  17. |
  18. |     Typing a <q|Q>, the right mouse button or selecting an object
  19. |     named "quit" will exit the program.
  20. |
  21. |===================================================================
  22. */
  23. #include <windows.h>
  24. /*
  25.  *  DV-Tools header files
  26.  */
  27. #include "std.h"                /* <stdio.h> etc., scalar & macro definitions */
  28. #include "dvstd.h"              /* public types & constants */
  29. #include "dvtools.h"            /* constants used by T routines */
  30. #include "dvGR.h"               /* constants used by window mgt & GR routines */
  31. #include "VOstd.h"              /* constants used by VO & VOob routines */
  32. #include "Tfundecl.h"           /* T routines (screens, drawports & views) */
  33. #include "VOfundecl.h"          /* VO routines (objects) */
  34. #include "VUerfundecl.h"        /* VUer routines (event handling routines) */
  35. #include "VPfundecl.h"          /* VP routines (put info from dgp & vdp) */
  36. #include "VGfundecl.h"          /* VG routines (get info from dgp & vdp) */
  37. //#include "GRkeysym.h"           /* key symbol definitions */
  38. #include "math.h"               /* math include */
  39.  
  40. /* Constants */
  41. #define  DVPATH            (char *)NULL
  42. #define  DISPFORMS_STB     (char *)NULL
  43. #define  DVDEVICE          (char *)NULL
  44. #define  DVCOLORTABLE      (char *)NULL
  45. #define  VIEW_NAME         "graph_scroll.v"
  46. #define  SCREEN_VIEWPORT   (RECTANGLE *)NULL
  47. #define  DRAWING_VIEWPORT  (RECTANGLE *)NULL
  48.  
  49. #define  SAMPLE_SIZE       50
  50. #define  DATA_SIZE       1000
  51.  
  52. #define  EXPOSE_LABEL       1
  53. #define  RESIZE_LABEL       2
  54. #define  BUTTON_LABEL       3
  55. #define  KEY_LABEL       4
  56.  
  57. #define  LEFT_BUTTON       1
  58. #define  RIGHT_BUTTON       3
  59. #define  SIMPLE_EDGE       (OBJECT)1
  60. #define  SCROLLBAR_CLIENT  (OBJECT)2
  61.  
  62. typedef  union
  63.      {
  64.        char string[10];
  65.        LABEL_SIZE size;
  66.        } Label_Union;
  67.  
  68. DRAWPORT drawport;              /* how & where to displat picture */
  69. OBJECT graph;                   /* graph object */
  70. DATAGROUP dgp;                  /* data group pointer */
  71. double *DataPtr,                /* Pointer to data element in array */
  72.   Data[DATA_SIZE];              /* array of data values */
  73. int Index;                      /* buffer for scroll bar */
  74. int Quit = NO;                  /* flag to quit program */
  75.  
  76. /* Functions defined in graph_scroll.c */
  77. int ExposeResizeHandler V_P_((OBJECT scr_client, EVENT_REQUEST request, int label, OBJECT loc, ADDRESS args));
  78. int HandlePressEvent V_P_((OBJECT client, EVENT_REQUEST request, int label, OBJECT loc, ADDRESS args));
  79. int HandleScrollbar V_P_((OBJECT client, EVENT_REQUEST request, int label, OBJECT loc, ADDRESS args));
  80. ADDRESS RebindVdps V_P_((OBJECT vd_obj, ADDRESS vdp, ADDRESS args));
  81. void InitData V_P_((void));
  82. void LabelTimeTics V_P_((ADDRESS args, double *value, ADDRESS output, TIC_DATA * tdp));
  83.  
  84. /*
  85.  *   MAIN PROGRAM
  86.  */
  87. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, 
  88.                      LPSTR lpCmdLine, int nCmdShow )
  89. {
  90.   INT argc = 0;
  91.   CHAR **argv;
  92.  
  93.   /* argv[1] - display device (default is DVDEVICE) */
  94.  
  95.   /* Define & initialize device name and view filename */
  96.   char *device_name = DVDEVICE; /* default device name */
  97.   char *view_name = VIEW_NAME;  /* default view name */
  98.  
  99.   /* Define display variables */
  100.   OBJECT screen;                /* display device, the window */
  101.   VIEW view;                    /* picture representation of the view file */
  102.  
  103.   /* Control loop variables */
  104.   OBJECT location;              /* the event representation */
  105.  
  106.   /* Other variables */
  107.   OBJECT drawing,               /* graphical representation of screen */
  108.     scrollbar;                  /* scrollbar input object */
  109.   ULONG pick_syms[4];           /* list of valid picks */
  110.  
  111.   argc = 0;
  112.   /*--------------------
  113.    *   Initialization
  114.    *
  115.    *   TInit:  perform the initialization of DV-Tools
  116.    *           TInit reads your configuration file and any
  117.    *           environment variables or logical names set.
  118.    */
  119.   make_argv(&argc,&argv,GetCommandLine());
  120.   TInit( DVPATH, DISPFORMS_STB );
  121.  
  122.   /*
  123.    *   TscOpenSet: open a device as a screen object using
  124.    *               specified attributes
  125.    *   TscErase:   erase the entire screen in the default
  126.    *               background color
  127.    *
  128.    *   Set exposure block to YES to insure the window
  129.    *   is ready for drawing when TdpDraw is called.
  130.    */
  131.   if (argc > 1)
  132.     device_name = argv[1];
  133.   screen = TscOpenSet( device_name, DVCOLORTABLE,
  134.                V_WINDOW_WIDTH, 500,
  135.                V_WINDOW_HEIGHT, 500,
  136.                        V_X_EXPOSURE_BLOCK, YES,
  137.                        V_ACTIVE_CURSOR, V_END_OF_LIST);
  138.   if (!screen)
  139.     {
  140.       printf ("Must specify device on command line or");
  141.       printf (" in DataViews configuration file.\n");
  142.       S_EXIT (EXIT_ERR);
  143.     }
  144.   TscErase (screen);
  145.  
  146.   /*
  147.    *   VOscWinEventMask:  sets the screen's window event mask
  148.    */
  149.   VOscWinEventMask ((ULONG) V_KEYPRESS | V_KEYRELEASE |
  150.                             V_BUTTONPRESS | V_BUTTONRELEASE |
  151.                             V_RESIZE | V_EXPOSE,
  152.                     (ULONG) 0);
  153.  
  154.   /*
  155.    *   VUerWinEventPost:  Posts a request for a window event.
  156.    *
  157.    *   Post event requests for "window" events - Expose and Resize.
  158.    */
  159.   VUerWinEventPost (screen, ExposeResizeHandler,
  160.             (ADDRESS) NULL, 0, EXPOSE_LABEL,
  161.             (ULONG) VUER_EXPOSE_EVENT);
  162.   VUerWinEventPost (screen, ExposeResizeHandler,
  163.             (ADDRESS) NULL, 0, RESIZE_LABEL,
  164.             (ULONG) VUER_RESIZE_EVENT);
  165.  
  166.   /*
  167.    *   VUerBoundaryEventPost:  Posts an event request
  168.    *
  169.    *   Post a request for a button event matching the left or right
  170.    *   mouse buttons, anywhere on the screen.  This is known as a
  171.    *   simple edge event.
  172.    */
  173.   pick_syms[0] = (ULONG) LEFT_BUTTON;
  174.   pick_syms[1] = (ULONG) RIGHT_BUTTON;
  175.   pick_syms[2] = V_END_OF_LIST;
  176.   VUerBoundaryEventPost ((OBJECT) SIMPLE_EDGE, HandlePressEvent,
  177.                          (ADDRESS) NULL, 0, BUTTON_LABEL,
  178.                          (ULONG) VUER_SE_EVENT, V_BUTTONPRESS, pick_syms);
  179.  
  180.   /*
  181.    *   Post an event request for a keypress event matching the
  182.    *   keys 'q' or 'Q', anywhere on the screen. This is used to
  183.    *   quit the program.  Key symbols are defined in GRkeysymdef.h.
  184.    */
  185.   pick_syms[0] = 0x071;
  186.   pick_syms[1] = 0x051;
  187.   pick_syms[2] = V_END_OF_LIST;
  188.   VUerBoundaryEventPost ((OBJECT) SIMPLE_EDGE, HandlePressEvent,
  189.                          (ADDRESS) NULL, 0, KEY_LABEL,
  190.                          (ULONG) VUER_SE_EVENT, V_KEYPRESS, pick_syms);
  191.  
  192.   /*
  193.    *   TviLoad:   Load a view in from a file,
  194.    *   TdpCreate: Create a drawport.
  195.    *              The drawport is attached to the screen object
  196.    *              specified while view specifies the view to be
  197.    *              displayed on the screen.
  198.    */
  199.   view = TviLoad (view_name);
  200.   if (!view)
  201.     {
  202.       printf ("Could not load view from file ");
  203.       printf ("%s.\n", view_name);
  204.       S_EXIT (EXIT_ERR);
  205.     }
  206.   drawport = TdpCreate (screen, view, SCREEN_VIEWPORT, DRAWING_VIEWPORT);
  207.  
  208.   /*
  209.    *  TviGetDrawing:  Gets a view's drawing object
  210.    *  TobForEachVdp:  Traverses all variable descriptors
  211.    *                  in an object
  212.    *
  213.    *  Traverse all variable descriptors in the drawing object
  214.    *  call the function RebindVdps for each variable descriptor.
  215.    */
  216.   drawing = TviGetDrawing (view);
  217.   TobForEachVdp (drawing, RebindVdps, (ADDRESS) NULL);
  218.  
  219.   /*
  220.    *  Initialize internal data buffers.
  221.    */
  222.   Index = 0;
  223.   DataPtr = &Data[0];
  224.  
  225.   /*
  226.    *  TdrGetNamedObject:  Gets a named object from a drawing.
  227.    *  VUerServiceResultPost:  Post a service result request.
  228.    *
  229.    *  Get the scrollbar input object and post a service result
  230.    *  request to monitor input within this object.
  231.    */
  232.   scrollbar = TdrGetNamedObject (drawing, "scrollbar");
  233.   VUerServiceResultPost (SCROLLBAR_CLIENT, HandleScrollbar,
  234.                          (ADDRESS) NULL, 0, scrollbar,
  235.                          INPUT_DONE | INPUT_ACCEPT, 0);
  236.  
  237.   /*
  238.    *  VOdgGetDgp:  Returns pointer to data group structure.
  239.    *
  240.    *  Get the graph object and it's data group pointer.
  241.    */
  242.   graph = TdrGetNamedObject (drawing, "graph");
  243.   dgp = VOdgGetDgp (graph);
  244.  
  245.   /*
  246.    *  VPdgticlabfcn:    Assign a tick labeling function to a data
  247.    *            group axis.
  248.    *
  249.    *  Assign our own tick labeling function to the graph.
  250.    *  This is necessary to label the ticks on the horizontal axis
  251.    *  correctly when the graph is scrolled.
  252.    */
  253.   VPdgticlabfcn (dgp, V_TIME_AXIS, (DV_TICLABELFUNPTR)LabelTimeTics, (char *) NULL, 0);
  254.  
  255.   /*
  256.    *  Initialize the data.
  257.    */
  258.   InitData ();
  259.  
  260.   /*
  261.    *  TdpDraw:  draw contents of drawport
  262.    */
  263.   TdpDraw (drawport);
  264.  
  265.   /*--------------------
  266.    *   Control loop
  267.    *
  268.    *   VOloWinEventPoll:   Poll for the next window event.
  269.    *               Wait until a masked event is generated.
  270.    *   VUerHandleLocEvent: Service the event.
  271.    *
  272.    *   Poll the event queue for events specified by the window
  273.    *   mask.  Events will be dispatched to the appropriate
  274.    *   handling routines by VUerHandleLocEvent. The event handler,
  275.    *   VUerHandleLocEvent will also handle and dispatch events occurring
  276.    *   within input objects. Stop when the Quit flag is set to YES.
  277.    */
  278.   FOREVER
  279.   {
  280.     location = VOloWinEventPoll (V_WAIT);
  281.     VUerHandleLocEvent (location);
  282.     if (Quit == YES)
  283.       break;
  284.   }
  285.  
  286.   /*--------------------
  287.    *   Termination
  288.    *
  289.    *   VUerClearAll: Clears a client's event requests
  290.    *   TdpDestroy:   Destroy the drawport,
  291.    *   TviDestroy:   Destroy the view, freeing the allocated memory
  292.    *   TscClose:     Close the display screen
  293.    *   TTerminate:   Perform the clean-up for DV-Tools
  294.    */
  295.   VUerClearAll (screen);
  296.   VUerClearAll (SIMPLE_EDGE);
  297.   VUerClearAll (SCROLLBAR_CLIENT);
  298.   TscErase (screen);
  299.   TdpDestroy (drawport);
  300.   TviDestroy (view);
  301.   TscClose (screen);
  302.   TTerminate ();
  303.   return (EXIT_OK);
  304. }
  305.  
  306. /*--------------------
  307.  * ExposeResizeHandler -- Service Routine which is called in
  308.  *     response to "window" events (Expose and Resize).  The
  309.  *     event requests that this routine services are posted
  310.  *       with VUerWinEventPost (above).  The "label" argument
  311.  *     tells the routine which request (Expose or Resize)
  312.  *     caused the routine to be called.
  313.  */
  314. /*ARGSUSED*/
  315. int 
  316. ExposeResizeHandler (scr_client, request, label, loc, args)
  317.      OBJECT scr_client;
  318.      EVENT_REQUEST request;
  319.      int label;
  320.      OBJECT loc;
  321.      ADDRESS args;
  322. {
  323.   switch (label)
  324.     {
  325.     case EXPOSE_LABEL:
  326.       TscRedraw (scr_client, VOloRegion (loc));
  327.       break;
  328.  
  329.     case RESIZE_LABEL:
  330.       TscReset (scr_client);
  331.       break;
  332.     }
  333.  
  334.   return (int) INPUT_USED;
  335. }
  336.  
  337. /*-------------------
  338.  *   HandlePressEvent -- Service Routine which is called in response
  339.  *     to ButtonPress and KeyPress events in the screen.  The event
  340.  *       request is posted with VUerBoundaryEventPost.  The "label"
  341.  *     argument tells the routine which request (ButtonPress or KeyPress)
  342.  *     caused the routine to be called. Then, the event is examined
  343.  *     to determine if the user has selected to quit the program.
  344.  *     The user may quit the program in several manners.
  345.  */
  346. /*ARGSUSED*/
  347. int 
  348. HandlePressEvent (client, request, label, loc, args)
  349.      OBJECT client;
  350.      EVENT_REQUEST request;
  351.      int label;
  352.      OBJECT loc;
  353.      ADDRESS args;
  354. {
  355.   char *obj_name;
  356.  
  357.   switch (label)
  358.     {
  359.     case BUTTON_LABEL:
  360.       switch (VOloButton (loc))
  361.         {
  362.         case LEFT_BUTTON:
  363.           obj_name = TloGetSelectedObjectName (loc);
  364.           if (obj_name)
  365.             if (strcmp (obj_name, "quit") == 0)
  366.               Quit = YES;
  367.           break;
  368.  
  369.         case RIGHT_BUTTON:
  370.           Quit = YES;
  371.           break;
  372.         }
  373.       break;
  374.  
  375.     case KEY_LABEL:
  376.       Quit = YES;
  377.       break;
  378.     }
  379.  
  380.   return (int) INPUT_USED;
  381. }
  382.  
  383.  
  384. /*------------------
  385.  *   HandleScrollbar -- called when the user uses the scrollbar.
  386.  *    Pressing on the scrollbar indicates the user would like
  387.  *    to scroll to a different position in the data.
  388.  */
  389. /*ARGSUSED*/
  390. int 
  391. HandleScrollbar (client, request, label, loc, args)
  392.      OBJECT client;
  393.      EVENT_REQUEST request;
  394.      int label;
  395.      OBJECT loc;
  396.      ADDRESS args;
  397. {
  398.   float start;
  399.  
  400.   /*  Make sure the user does not scroll off the end of the data */
  401.   if (Index > (DATA_SIZE - SAMPLE_SIZE))
  402.     Index = DATA_SIZE - SAMPLE_SIZE;
  403.  
  404.   /*
  405.    *  Set DataPtr (the variable to which the graph's vdp is rebound) to
  406.    *  point to the appropriate location in the data array.
  407.    */
  408.   DataPtr = &Data[Index];
  409.  
  410.   /*
  411.    *  VPdgtime_start_incr:  Sets the start and increment values of
  412.    *                the time axis.
  413.    *  TdpDrawObject:        Draw an object to the drawport
  414.    *
  415.    *  Set the "start" time value for the graph, this will be
  416.    *  passed to the tick labeling function to generate
  417.    *  appropriate tick labels.
  418.    */
  419.   start = (float) Index;
  420.   VPdgtime_start_incr (dgp, &start, (float *) NULL);
  421.   VPdgdfreset (dgp);
  422.   TdpDrawObject (drawport, graph);
  423.  
  424.   return (int)INPUT_USED;
  425. }
  426.  
  427. /*-------------
  428.  *   RebindVdps -- modify the variable descriptor to use our own
  429.  *    program variable as the memory buffer.  The variable
  430.  *    descriptor which had previously pointed to a data source
  431.  *    variable for the data will now look at our program variable
  432.  *    for the data information.
  433.  */
  434. /*ARGSUSED*/
  435. ADDRESS 
  436. RebindVdps (vd_obj, vdp, args)
  437.      OBJECT vd_obj;
  438.      ADDRESS vdp;
  439.      ADDRESS args;
  440. {
  441.   char *name;                   /* variable descriptor name */
  442.  
  443.   /*
  444.    *   VGvdvarname:  Gets a pointer to the variable name
  445.    *
  446.    *   The name of the variable descriptor is used to
  447.    *   determine which buffer to rebind to.  If the
  448.    *   variable does not have a name then return.
  449.    */
  450.   name = VGvdvarname (vdp);
  451.   if (!name)
  452.     return V_CONTINUE_TRAVERSAL;
  453.  
  454.   /*
  455.    *   TvdPutBuffer:  Sets a new variable descriptor buffer
  456.    *
  457.    *   Rebind vdp to internal program variable.
  458.    */
  459.   if (S_STRCMP (name, "Index") == 0)
  460.     TvdPutBuffer (vdp, (ADDRESS) & Index);
  461.   else if (strcmp (name, "Data") == 0)
  462.     {
  463.       TvdPutBuffer (vdp, (ADDRESS) & DataPtr);
  464.  
  465.       /*
  466.        *  VPvd_accmode:  Set the data access mode to direct or indirect.
  467.        *
  468.        *  Set the "access mode" of the vdp named Data to INDIRECT.
  469.        *  This means the variable DataPtr contains the address of
  470.        *  the data, not the actual data.
  471.        */
  472.       VPvd_accmode (vdp, V_INDIR_ACCESS);
  473.     }
  474.  
  475.   return V_CONTINUE_TRAVERSAL;
  476. }
  477.  
  478.  
  479. /*-----------
  480.  *   InitData -- initialize the Data array to "interesting" values.
  481.  *       This way we can tell visually if the graph is scrolling.
  482.  *       In a real application, Data would contain your historical data.
  483.  */
  484. void InitData ()
  485. {
  486.   double scale, sin_val;
  487.   int i;
  488.  
  489.   for (i = 0; i < DATA_SIZE; i++)
  490.     {
  491.       scale =  (double) i / (double)DATA_SIZE;
  492.       sin_val = sin ((double) i / (double)3.0);
  493.       Data[i] = sin_val * scale;
  494.     }
  495. }
  496.  
  497. /*----------------
  498.  *   LabelTimeTics -- the tic label function for the graph.
  499.  */
  500. /*ARGSUSED*/
  501. void 
  502. LabelTimeTics (args, value, output, tdp)
  503.      ADDRESS args;
  504.      double *value;
  505.      ADDRESS output;
  506.      TIC_DATA *tdp;
  507.   Label_Union *label_output = (Label_Union *)output;
  508.  
  509.   /*
  510.    *  "value" represents the value associated with the tick mark.
  511.    *
  512.    *  If "value" is NULL, "label_output" points to a LABEL_SIZE structure which
  513.    *  receives the size of the text string.  If "value" is non-NULL then
  514.    *  label_output is a pointer to a string array which receives the tick
  515.    *  label generated for this "value".
  516.    */
  517.   if (value == (double *) NULL)
  518.     {
  519.       label_output->size.StringLength = 9;
  520.       label_output->size.NumLines = 2;
  521.       label_output->size.LongestLine = 5;
  522.     }
  523.   else
  524.     sprintf (label_output->string, "Index\n%d", (int) * value);
  525. }
  526.  
  527.  
  528.  
  529.